<?php

declare(strict_types=1);

namespace app\common\traits;

use think\facade\Db;

/**
 * Service层 服务公共方法 [业务、接口、服务]
 * @author:kaige
 * @update:2022-06-12
 * @copyright ©2022 泉州市盛筑信息科技有限公司 版权所有
 * @explain 修改此文档时必须在团队说明原由
 */
trait ServiceTrait
{
  /**
   * 根据主键获取信息 - 接口
   * @param int $id 主键
   * @param array|bool $where 查询条件
   * @param array $field 需要显示的字段
   * @return mixed 返回实例对象 
   */
  public function getInfoById($id, $where = true, $field = [])
  {
    return $this->dao->getInfoById($id, $where, $field);
  }

  /**
   * 根据查询条件获取信息 - 接口
   * @param array|bool $where 查询条件
   * @param array $field 需要显示的字段
   * @return mixed 返回实例对象
   */
  public function getInfoByWhere($where = true, $field = [])
  {
    return $this->dao->getInfoByWhere($where, $field);
  }

  /**
   * 根据查询条件获取信息 - 接口
   * @param array|bool $where 查询条件
   * @param array $field 需要显示的字段
   * @return mixed 返回实例对象
   */
  public function getInfoByCacheWhere($where = true, $field = [])
  {
    return $this->dao->getInfoByCacheWhere($where, $field);
  }

  /**
   * 根据默认查询字段查询 - 接口
   * @param mixed $name 默认字段
   * @param array|bool $where 查询条件
   * @return mixed 返回实例对象
   */
  public function getInfoByName($name, $where = true, $field = [])
  {
    return $this->dao->getInfoByName($name, $where, $field);
  }

  /**
   * 查询满足条件的数量 - 接口
   * @param array|bool $where 查询条件
   * @return int 返回数量，无数据返回0
   */
  public function getTotal($where = true)
  {
    return $this->dao->getTotal($where);
  }

  /**
   * 分页查询 - 接口
   * @param int $page 当前页
   * @param int $limit 每页数量 默认 20
   * @param array|bool $where 查询条件
   * @param array $order 排序规则
   * @param array $field 显示的字段
   * @return array 返回数组
   */
  public function getLists($page = 1, $limit = 20, $where = true, $order = ['id' => 'asc'], $field = [])
  {
    return $this->dao->getLists($page, $limit, $where, $order, $field);
  }

  /**
   * 查询所有数据 - 接口
   * @param array|bool $where 查询条件
   * @param array $order 排序
   * @return array
   */
  public function getListAll($where = true, $order = ['id' => 'asc'], $field = [])
  {
    return $this->dao->getListAll($where, $order, $field);
  }

  /**
   * 新增 - 接口
   * @param array $data
   * @return mixed 返回实例对象或false
   */
  public function add($data)
  {
    return $this->dao->add($data);
  }

  /**
   * 更新数据 - 接口
   * @param int $id
   * @param array $data
   * @return mixed
   */
  public function update($id, $data)
  {
    return $this->dao->update($id, $data);
  }

  /**
   * 更新数据按条件 - 接口
   * @param array $where
   * @param array $data
   * @return mixed
   */
  public function updateByWhere($where, $data)
  {
    return $this->dao->updateByWhere($where, $data);
  }

  /**
   * 根据主键删除单条数据 - 接口
   * @param int $id
   * @return bool
   */
  public function delete($id)
  {
    return $this->dao->delete($id);
  }

  /**
   * 根据条件删除数据 - 接口
   * @param array $where
   * @return bool
   */
  public function deleteByWhere($where)
  {
    return $this->dao->deleteByWhere($where);
  }

  /**
   * 批量删除 $ids不能=0 - 接口
   * @param array|string $ids  string:'1,2,...'
   * @return bool
   */
  public function multiDelete($ids)
  {
    return $this->dao->multiDelete($ids);
  }

  /**
   * 单字段值更新-允许INT字段，必须在model设置允许的字段 uaField=[...] - 接口
   * @param int $id
   * @param string $field
   * @param mixed $val
   * @return bool
   */
  public function updateField($id = 0, $key = '', $val)
  {
    return $this->dao->updateField($id, $key, $val);
  }

  /**
   * 根据主键获取单字段值 - 接口
   * @param int $id 主键
   * @param string $field 字段名
   * @return mixed
   */
  public function oneField($id = 0, $field = '')
  {
    return $this->dao->oneField($id, $field);
  }

  //--------------------------关联取列表（开始）--------------------------
  /**
   * 列表是否关联 格式 'a,b,c' / ['a','b','c']
   * 如果存在关联，在model层要加入关联的(with) 函数
   */
  public function _list_with()
  {
    return [];
  }

  /**
   * 列表查询条件
   */
  public function _list_where($data)
  {
    return [
      'where' => isset($data['where']) ? $data['where'] : [],
      'order' => isset($data['order']) ? $data['order'] : [],
      'field' => isset($data['field']) ? $data['field'] : ['*'],
    ];
  }

  /**
   * 格式化数据
   */
  public function _list_format($data)
  {
    return $data;
  }

  /**
   * 控制关联子表的字段部分显示
   */
  public function _list_visible()
  {
    //在service层定义此方法，返回数组。['关联with函数名' => ['字段1', '字段2'], '关联with函数名' => ['字段1', '字段2'], ...];
    return [];
  }

  /**
   * 获取关联列表数据，默认分页
   * @param array $data
   * @param boolean $isPage
   * @return array [count,data]
   */
  public function _list($data, $isPage = true)
  {
    $inData = [];
    $objwith = $this->_list_with();
    if (!empty($objwith)) {
      $inData['with'] = $objwith;
    }
    //传入的with 优先于方法的with;自定义性较强
    if(isset($data['with']) && !empty($data['with'])){
      $inData['with'] = $data['with'];
      unset($data['with']);
    }
    $arraywhere = $this->_list_where($data);
    if (isset($arraywhere['whereOr']) && !empty($arraywhere['whereOr'])) {
      $inData['whereOr'] = $arraywhere['whereOr'];
    }
    $inData['where'] = $arraywhere['where'];
    $inData['field'] = $arraywhere['field'];

    $obj_order = $arraywhere['order'];
    if (empty($obj_order)) {
      $obj_order = ['id' => 'desc'];
    }
    $inData['order'] = $obj_order;

    if ($isPage) {
      if (isset($data['limit'])) {
        $limit = (int)$data['limit'];
      } else {
        $limit = 20;
      }
      $inData['limit'] = $limit;
      if (isset($data['page'])) {
        $page = (int)$data['page'];
      } else {
        $page = 1;
      }
      $begin = intval(($page - 1) * $limit);
      $inData['begin'] = $begin;

      if (empty($objwith)) {
        $count = $this->dao->getCount($inData);
        $list = $this->dao->getList($inData);
      } else {
        $count = $this->dao->getCountWith($inData);
        $list = $this->dao->getListWith($inData);
      }
      
    } else {
      if (empty($objwith)) {
        $list = $this->dao->getList($inData, false);
      } else {
        $list = $this->dao->getListWith($inData, false);
      }
      $count = count($list);
    }
    if ($count > 0) {
      //是否控制关联子表的字段部分显示
      $visibleField = $this->_list_visible();
      if (!empty($visibleField) && !$list->isEmpty()) {
        $list = $list->visible($visibleField)->toArray();
      } else {
        $list = $list->toArray();
      }
      // 格式化数据
      $list = $this->_list_format($list);

      return _layui($count, $list);
    }
    return _layui(0, []);
  }

  /**
   * 获取关联列表数据，取总记录数
   * @param array $data
   * @param boolean $isPage
   * @return array [count,data]
   */
  public function _count($data, $isPage = true)
  {
    $inData = [];
    $objwith = $this->_list_with();
    if (!empty($objwith)) {
      $inData['with'] = $objwith;
    }
    $arraywhere = $this->_list_where($data);
    if (isset($arraywhere['whereOr']) && !empty($arraywhere['whereOr'])) {
      $inData['whereOr'] = $arraywhere['whereOr'];
    }
    $inData['where'] = $arraywhere['where'];
    $inData['field'] = $arraywhere['field'];

    if (empty($objwith)) {
      $count = $this->dao->getCount($inData);
    } else {
      $count = $this->dao->getCountWith($inData);
    }
    return $count;
  }
  //--------------------------关联取列表（结束）-----------------------------

  /**
   * 查询已经软删除的列表，无关联
   * @param array $data 查询条件
   * @param bool $isPage 是否分页 默认分页
   * @return mixed
   */
  public function getRecycleList($data = [], $isPage = true)
  {
    $list = $this->dao->getRecycleList($data, $isPage);
    $count = $this->dao->getRecycleCount($data);
    if (!empty($list)) $list = $list->toArray();
    // 格式化数据
    $list = $this->_list_format($list);

    return _layui($count, $list);
  }

  /**
   * 保存表单数据
   * @param $data
   * @return array
   */
  public function saveForm($data)
  {
    if (empty($data)) {
      return _err(1002);
    }
    if (isset($data['id']) && !empty($data['id'])) {
      $result = $this->dao->update($data['id'], $data);
      if ($result) {
        return _ok(1021);
      }
    } else {
      $result = $this->dao->add($data);
      if ($result) {
        $return =  _ok(1023);
        if (!empty($result->id)) {
          $return['data'] = $result->id;
        }
        return $return;
      }
    }
    return _err(1005);
  }

  /**
   * 删除数据，支持批量删除 - 接口
   * @param string $id 
   * @return array
   */
  public function _del($id)
  {
    return $this->dao->_del($id);
  }

  /**
   * 根据主键获取一条记录 - 兼容旧版
   * 建议使用 getInfoById
   * @return array
   */
  public function _one($id = 0)
  {
    $info = $this->dao->getInfoById($id);
    if ($info) {
      $info = $info->toArray();
    }
    return $info;
  }

  //--------------------------关联流程取列表（开始）--------------------------
  /**
   * 列表查询条件
   * 分主、附表条件，各自分开
   */
  // public function _flow_list_where($data)
  // {
  //   return [
  //     'mainWhere' => isset($data['mainWhere']) ? $data['mainWhere'] : [],
  //     'sideWhere' => isset($data['sideWhere']) ? $data['sideWhere'] : [],
  //     'mainOrder' => isset($data['mainOrder']) ? $data['mainOrder'] : [],
  //     'sideOrder' => isset($data['sideOrder']) ? $data['sideOrder'] : [],
  //     'mainField' => isset($data['mainField']) ? $data['mainField'] : [],
  //     'sideField' => isset($data['sideField']) ? $data['sideField'] : [],
  //   ];
  // }

  public function _flow_list_where_modu($post)
  {
    return [];
  }

  /**
   * 重写 表格过滤条件
   * @param $post
   * @return array
   */
  public function _flow_list_where($post)
  {
    $where = [];
    $where1 = [];
    $where1Or = [];
    $where[] = ['modu_id', '=', $this->moduId];
    if (isset($post['company_id']) && $post['company_id'] != "") {
      $where[] = ['company_id', 'like', '%' . $post['company_id'] . '%'];
    }
    if (isset($post['put_uid']) && $post['put_uid'] != "") {
      $where[] = ['put_uid', '=', $post['put_uid']];
    }
    if (isset($post['is_put']) && $post['is_put'] != "") {
      $where[] = ['is_put', '=', $post['is_put']];
    }
    if (isset($post['search_status']) && $post['search_status'] != "") {
      $where[] = ['status', '=', $post['search_status']];
    } elseif (isset($post['status']) && $post['status'] != "") {
      $where[] = ['status', '=', $post['status']];
    }
    if ($this->keywords_field != '') {
      if (isset($post['keywords']) && !empty($post['keywords'])) {
        $where1[] = [$this->keywords_field, 'like', '%' . $post['keywords'] . '%'];
      }
    }
    //过滤我的。
    if (isset($post['isfilter_my']) && $post['isfilter_my'] === 1) {
      $where[] = ['handle_uid|put_uid', '=', $post['user_id']];
    } else { //权限过滤
      $rs = new \app\common\service\sys\RoleService();
      $arrwh = $rs->getRoleDataAuth($post['user_id'], 'handle_uid'); //操作人
      $where = array_merge_recursive($where, $arrwh);
    }

    $tmpwhmodu = $this->_flow_list_where_modu($post);
    if (!empty($tmpwhmodu)) {
      $where = array_merge_recursive($where, $tmpwhmodu[0]);
      $where1 = array_merge_recursive($where1, $tmpwhmodu[1]);
      $where1Or = isset($tmpwhmodu[2]) ? $tmpwhmodu[2] : [];
    }
    $result['mainWhere'] = $where;
    $result['sideWhere'] = $where1;
    $result['sideWhereOr'] = $where1Or;
    $result['sideField'] = ['*'];
    $result['sideOrder'] = ['id desc'];
    return $result;
  }

  /**
   * 格式化数据
   */
  public function _flow_list_format($data)
  {
    return $data;
  }

  /**
   * 控制关联子表的字段部分显示
   */
  public function _flow_list_visible()
  {
    //在service层定义此方法，返回数组。['关联with函数名' => ['字段1', '字段2'], '关联with函数名' => ['字段1', '字段2'], ...];
    return [];
  }

  /**
   * 获取关联列表数据，必分页
   * @param array $data
   * @return array layui.table.data
   */
  public function _flow_list($data)
  {
    $inData = [];
    $arraywhere = $this->_flow_list_where($data);
    if (isset($arraywhere['sideWhereOr']) && !empty($arraywhere['sideWhereOr'])) {
      $inData['sideWhereOr'] = $arraywhere['sideWhereOr'];
    }
    $inData['mainWhere'] = $arraywhere['mainWhere'];
    $inData['sideWhere'] = $arraywhere['sideWhere'];
    $inData['sideField'] = $arraywhere['sideField'];

    if (isset($data['alias']) && $data['alias']) {
      $inData['alias'] = $data['alias'];
    }

    $inData['sideOrder'] = $arraywhere['sideOrder'];
    if (empty($inData['sideOrder'])) {
      $inData['sideOrder'] = ['id' => 'desc'];
    }

    if (isset($data['limit'])) {
      $limit = (int)$data['limit'];
    } else {
      $limit = 20;
    }
    $inData['limit'] = $limit;

    if (isset($data['page'])) {
      $page = (int)$data['page'];
    } else {
      $page = 1;
    }
    $inData['page'] =  $page;
    $begin = intval(($page - 1) * $limit);
    $inData['begin'] = $begin;

    $result = $this->dao->getListFlow($inData);
    $count = $result['count'];

    if ($count > 0) {
      // 格式化数据
      $list = $this->_flow_list_format($result['list']);
      return _layui($count, $list);
    }
    return _layui(0, []);
  }
  //--------------------------关联流程取列表（结束）-----------------------------

  /**
   * 获取流程单据 -- 接口
   */
  public function getflow($id = 0)
  {
    return $this->dao->getflow($id);
  }
}
